package com.simpou.commons.utils.file.filter;

import com.simpou.commons.utils.file.FileHelper;
import com.simpou.commons.utils.validation.Assertions;
import java.io.File;
import java.io.FilenameFilter;

/**
 * Verifica se os caminhos completos de diretórios conteém sub-diretórios em uma
 * ordem estabelecida.
 *
 * @author Jonas Pereira
 * @since 2013-09-18
 */
public final class SubDirectoryFileNameFilter implements FilenameFilter {

    private final String[] parts;

    private final boolean exact;

    /**
     * @param exact Indica se todas as partes devem estar todas presentes, juntas e na ordem indicada.
     * @param parts Partes que devem estar contidas no caminho completo do diretório na ordem indicada.
     */
    public SubDirectoryFileNameFilter(final boolean exact, final String... parts) {
        this.parts = Assertions.notEmpty(String.class, parts);
        this.exact = exact;
    }

    @Override
    public boolean accept(final File dir, final String name) {
        final String[] dirParts = FileHelper.normalizeFilePathDelim(dir.getAbsolutePath()).split("/");

        int firstIndex = -1;
        for (int i = 0; i < dirParts.length; i++) {
            if (parts[0].equals(dirParts[i])) {
                firstIndex = i;
                break;
            }
        }

        boolean accepted;
        if (firstIndex < 0) {
            accepted = false;
        } else {
            int lastFound = -1;
            int iterParts = 1;
            int iterDirParts = firstIndex + 1;
            while (iterDirParts < dirParts.length && iterParts < parts.length) {
                if (exact) {
                    if (parts[iterParts].equals(dirParts[iterDirParts])) {
                        lastFound = iterParts;
                        iterParts++;
                    } else {
                        break;
                    }
                } else {
                    if (parts[iterParts].equals(dirParts[iterDirParts])) {
                        lastFound = iterParts;
                        iterParts++;
                    }
                }
                iterDirParts++;
            }
            accepted = lastFound == parts.length - 1;
        }
        return accepted;
    }
}
